﻿using CS795.TravelAgency.Domain;
using CS795.TravelAgency.Models;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;

namespace CS795.TravelAgency.Controllers
{
    public class AccountController : Controller
    {
        private TravelAgencyContext context = new TravelAgencyContext();
        
        [RequireHttps]
        [HttpGet]
        public ActionResult LogOn(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            return View();
        }

        [RequireHttps]
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LogOn(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (Membership.Provider.ValidateUser(model.UserName, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    return RedirectToLocal(returnUrl);
                }

                ModelState.AddModelError("", "Invalid username or password.");
            }
            return View(model);
        }

        [RequireHttps]
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }

        [RequireHttps]
        [HttpGet]
        [Authorize]
        public ActionResult Manage(string message)
        {
            ViewBag.StatusMessage = message ?? "";
            ViewBag.ReturnUrl = Url.Action("Manage");
            return View();
        }

        [RequireHttps]
        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public ActionResult Manage(ManageUserViewModel model)
        {
            if (ModelState.IsValid)
            {
                string username = User.Identity.Name;
                if (Membership.Provider.ChangePassword(username, model.OldPassword, model.NewPassword))
                {
                    return RedirectToAction("Manage", new { message = "Your password has been changed!" });
                }
                else
                {
                    return RedirectToAction("Manage", new { message = "Failed to change your password!" });
                }
            }
            return View(model);
        }

        [RequireHttps]
        [HttpGet]
        public ActionResult Register()
        {
            return View();
        }

        [RequireHttps]
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                MembershipCreateStatus status;
                MembershipUser newUser = Membership.Provider.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out status);
                if (status == MembershipCreateStatus.Success)
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, false);
                    return RedirectToAction("Index", "Home");
                }

                ModelState.AddModelError("", "Username is already taken.  Please select a unique username.");
            }
            return View(model);
        }

        [RequireHttps]
        [HttpGet]
        [Authorize(Roles = "Administrators, Agents")]
        public ActionResult Create(string message, string returnUrl)
        {
            ViewBag.StatusMessage = message ?? "";
            ViewBag.ReturnUrl = returnUrl;
            if (User.IsInRole("Administrators"))
            {
                ViewBag.Roles = Roles.Provider.GetAllRoles().AsEnumerable();
            }
            else
            {
                ViewBag.Roles = (new[] { "Customers" }).AsEnumerable();
            }
            return View();
        }

        [RequireHttps]
        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "Administrators, Agents")]
        public ActionResult Create(CreateViewModel model, string message, string returnUrl)
        {
            if (User.IsInRole("Administrators"))
            {
                ViewBag.Roles = Roles.Provider.GetAllRoles().AsEnumerable();
            }
            else
            {
                ViewBag.Roles = (new[] { "Customers" }).AsEnumerable();
            }
            ViewBag.StatusMessage = message ?? "";
            if (ModelState.IsValid)
            {
                MembershipCreateStatus status;
                MembershipUser newUser = Membership.Provider.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out status);
                if (status == MembershipCreateStatus.Success)
                {
                    Roles.Provider.RemoveUsersFromRoles(new string[] { model.UserName }, new string[] { "Customers" });
                    Roles.Provider.AddUsersToRoles(new string[] { model.UserName }, new string[] { model.Role });
                    if (string.IsNullOrEmpty(returnUrl))
                    {
                        return RedirectToAction("Create", new { message = "User has been created!" });
                    }
                    else
                    {
                        return RedirectToLocal(returnUrl);
                    }
                }

                ModelState.AddModelError("", "Username is already taken.  Please select a unique username.");
            }
            return View(model);
        }

        #region Utility Functions
        private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
        #endregion
    }
}